package com.frank.oj.manager;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.frank.model.entity.msg.AdminSysNotice;
import com.frank.model.entity.msg.UserSysNotice;
import com.frank.oj.model.vo.SysMsgVO;
import com.frank.oj.service.entity.msg.AdminSysNoticeEntityService;
import com.frank.oj.service.entity.msg.UserSysNoticeEntityService;
import com.frank.oj.shiro.AccountProfile;
import org.apache.shiro.SecurityUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author frank
 * @Date 2024/1/25
 */
@Component
public class NoticeManager {
    @Resource
    private AdminSysNoticeEntityService adminSysNoticeEntityService;
    @Resource
    private UserSysNoticeEntityService userSysNoticeEntityService;
    @Resource
    private ApplicationContext applicationContext;

    /**
     * 异步通知：新用户
     *
     * @param uuid 用户id
     */
    public void syncNoticeToNewRegisterUser(String uuid) {
        LambdaQueryWrapper<AdminSysNotice> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(AdminSysNotice::getType, "All")
                .le(AdminSysNotice::getGmtCreate, new Date())
                .eq(AdminSysNotice::getState, true);
        List<AdminSysNotice> adminSysNotices = adminSysNoticeEntityService.list(queryWrapper);
        if (adminSysNotices.size() == 0) {
            return;
        }
        List<UserSysNotice> userSysNoticeList = new ArrayList<>();
        for (AdminSysNotice adminSysNotice : adminSysNotices) {
            UserSysNotice sysNotice = new UserSysNotice();
            sysNotice.setType("Sys")
                    .setSysNoticeId(adminSysNotice.getId())
                    .setRecipientId(uuid);

            userSysNoticeList.add(sysNotice);
        }
        userSysNoticeEntityService.saveOrUpdateBatch(userSysNoticeList);
    }

    public IPage<SysMsgVO> getSysNotice(Integer limit, Integer currentPage) {
        if (currentPage == null || currentPage < 1) currentPage = 1;
        if (limit == null || limit < 1) limit = 5;

        AccountProfile userRole = (AccountProfile) SecurityUtils.getSubject().getPrincipal();
        IPage<SysMsgVO> sysNotice = userSysNoticeEntityService.getSysNotice(limit, currentPage, userRole.getUid());

        applicationContext.getBean(NoticeManager.class).updateSysOrMineMsgRead(sysNotice);

        return sysNotice;
    }

    public IPage<SysMsgVO> getMineNotice(Integer limit, Integer currentPage) {
        if (currentPage == null || currentPage < 1) currentPage = 1;
        if (limit == null || limit < 1) limit = 5;

        AccountProfile userRole = (AccountProfile) SecurityUtils.getSubject().getPrincipal();

        IPage<SysMsgVO> mineNotice = userSysNoticeEntityService.getMineNotice(limit, currentPage, userRole.getUid());
        applicationContext.getBean(NoticeManager.class).updateSysOrMineMsgRead(mineNotice);

        return mineNotice;
    }

    @Async
    public void updateSysOrMineMsgRead(IPage<SysMsgVO> userMsgList) {
        List<Long> idList = userMsgList.getRecords().stream()
                .filter(userMsgVo -> !userMsgVo.getState())
                .map(SysMsgVO::getId)
                .collect(Collectors.toList());

        if (idList.isEmpty()) {
            return;
        }
        LambdaUpdateWrapper<UserSysNotice> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(UserSysNotice::getId, idList)
                .set(UserSysNotice::getState, true); //标记已读

        userSysNoticeEntityService.update(updateWrapper);
    }


}
